package com.smsc.headend.task.engine.handler.impl.metercontrol;

import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONUtil;
import com.smsc.headend.common.enums.errorcode.TaskHandlerErrorCode;
import com.smsc.headend.common.utils.RedisKeys;
import com.smsc.headend.common.utils.RedisUtils;
import com.smsc.headend.module.data.enums.OperationGroup;
import com.smsc.headend.module.data.enums.OperationName;
import com.smsc.headend.module.protocol.DeviceData;
import com.smsc.headend.module.protocol.cosem.bo.CosemData;
import com.smsc.headend.module.task.consts.TaskKafkaTopic;
import com.smsc.headend.module.task.dto.AtomicTask;
import com.smsc.headend.module.task.dto.Task;
import com.smsc.headend.module.task.dto.TaskResult;
import com.smsc.headend.task.engine.dao.TaskDAO;
import com.smsc.headend.task.engine.exception.UDISTaskHandlerException;
import com.smsc.headend.task.engine.handler.TaskHandler;
import com.smsc.headend.task.engine.service.CosemXmlService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;

import java.nio.charset.Charset;
import java.util.Map;

/**
 * @author wxh
 * @date 2020/11/30 10:47
 */
@Slf4j
public class ReadControlModeHandler implements TaskHandler {
    @Autowired
    CosemXmlService cosemXmlService;

    @Autowired
    TaskDAO taskDAO;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    KafkaTemplate kafkaTemplate;

    @Override
    public int handle(Task task, AtomicTask atomicTask, DeviceData deviceData, String actionResult) throws UDISTaskHandlerException {
        if (!(deviceData instanceof CosemData)) {
            throw new UDISTaskHandlerException(TaskHandlerErrorCode.DEVICE_DATA_TYPE_NOT_SUPPORT.toString());
        }

        CosemData cosemData = (CosemData) deviceData;
        String value = cosemData.getValue();
        String type = cosemData.getType();
        Integer controlMode = Convert.toInt(cosemXmlService.getData(type, value));
        log.debug("controlMode" + controlMode);
        boolean flag = (atomicTask.getGroupId().longValue() == OperationGroup.ConnectArmed.getId()
                || atomicTask.getGroupId().longValue() == OperationGroup.Connect.getId())
                && atomicTask.getOperationId().intValue() == OperationName.GetControlMode.getId();
        if (flag) {
            log.debug("set redis value of OriginalMode");
            redisUtils.hset(RedisKeys.getHardOriginalModeKey(task.getTaskNo()), "1", controlMode, 600);
        }
        return 1;
    }

    @Override
    public int handleFailure(Task task, AtomicTask atomicTask, String message) {
        log.info("error {}, ", message);
        if (atomicTask.getGroupId() == OperationGroup.ConnectArmed.getId().intValue()
                || atomicTask.getGroupId() == OperationGroup.Connect.getId().intValue()
                || atomicTask.getGroupId() == OperationGroup.Disconnect.getId().intValue()
                || atomicTask.getGroupId() == OperationGroup.CheckCdc.getId().intValue()) {
            String key = "message";
            Map<String, Object> m = JSONUtil.toBean(task.getParamJson(), Map.class);
            key = m.get("seq") != null ? Convert.toStr(m.get("seq")) : key;
            String stepOperationName = OperationName.forId(atomicTask.getOperationId()).getName();
            if (task.getIsODR()) {
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), key, String.format("step %s failed, [%s]", stepOperationName, message), 3600l, false);
            }
        }
        return -1;
    }
}
